package com.practice.zookeeper.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.practice.zookeeper.server.annotation.RpcAnnotation;
import com.practice.zookeeper.server.zk.IRegistryCenter;

public class RpcServer {
	
	private static final ExecutorService executor = Executors.newCachedThreadPool();
	
	Map<String, Object> handlerMap = new HashMap<>();
	
	private IRegistryCenter registryCenter;
	private String serviceAddress;
	
	public RpcServer(IRegistryCenter registryCenter, String serviceAddress) {
		super();
		this.registryCenter = registryCenter;
		this.serviceAddress = serviceAddress;
	}
	
	public void bind(Object... services) {
		for (Object service : services) {
			RpcAnnotation annotation = service.getClass().getAnnotation(RpcAnnotation.class);
			String serviceName = annotation.value().getName();
			String version = annotation.version();
			if (version != null && !"".equals(version)) {
				serviceName = serviceName + "-" + version;
			}
			handlerMap.put(serviceName, service);
		}
	}

	public void publisher() {
		ServerSocket serverSocket = null;
		try {
			String[] adds = serviceAddress.split(":");
			serverSocket = new ServerSocket(Integer.parseInt(adds[1]));
			
			for (String interfaceName : handlerMap.keySet()) {
				registryCenter.register(interfaceName, serviceAddress);
			}
			while(true) {
				Socket socket = serverSocket.accept();
				executor.execute(new ProcessorHandler(socket, handlerMap));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (serverSocket != null) {
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
